#include <iostream>
#include <fstream>
#include <filesystem>
#include <sstream>
#include <vector>
#include <termios.h>
#include <unistd.h>
#include "json.hpp"

using json = nlohmann::json;

// ANSI颜色代码
#define COLOR_RESET   "\033[0m"
#define COLOR_RED     "\033[31m"
#define COLOR_GREEN   "\033[32m"
#define COLOR_YELLOW  "\033[33m"
#define COLOR_BLUE    "\033[34m"
#define COLOR_MAGENTA "\033[35m"
#define COLOR_CYAN    "\033[36m"
#define COLOR_WHITE   "\033[37m"

// 配置文件路径
const std::string CONFIG_FILE = "config.json";
// 默认配置
json config = {
    {"version", "1.0"},
    {"dataDirectory", "data"}
};

// 初始化配置文件
void initializeConfig() {
    if (!std::filesystem::exists(CONFIG_FILE)) {
        std::ofstream configStream(CONFIG_FILE);
        configStream << std::setw(4) << config << std::endl;
    } else {
        std::ifstream configStream(CONFIG_FILE);
        configStream >> config;
    }
}

// 保存配置文件
void saveConfig() {
    std::ofstream configStream(CONFIG_FILE);
    configStream << std::setw(4) << config << std::endl;
}

// 创建用户
void createUser(const std::vector<std::string>& args) {
    if (args.size() < 3) {
        std::cout << COLOR_RED << "{\"error\": \"参数无效。用法：createuser <username> <password>\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::string username = args[1];
    std::string password = args[2];

    json user = {
        {"username", username},
        {"password", password}
    };

    std::string path = config["dataDirectory"].get<std::string>() + "/user_" + username + ".json";
    std::ofstream userFile(path);
    userFile << std::setw(4) << user << std::endl;

    std::cout << COLOR_GREEN << "{\"message\": \"用户已创建\", \"user\": " << user << "}" << COLOR_RESET << std::endl;
}

// 创建表
void createTable(const std::vector<std::string>& args) {
    if (args.size() < 3) {
        std::cout << COLOR_RED << "{\"error\": \"参数无效。用法：createtable <tableName> <schemaJSON>\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::string tableName = args[1];
    std::string schemaStr = args[2];
    json schema;

    try {
        schema = json::parse(schemaStr);
    } catch (json::parse_error& e) {
        std::cout << COLOR_RED << "{\"error\": \"无效的JSON模式\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::string path = config["dataDirectory"].get<std::string>() + "/" + tableName + ".json";
    std::ofstream tableFile(path);
    tableFile << std::setw(4) << schema << std::endl;

    std::cout << COLOR_GREEN << "{\"message\": \"表已创建\", \"table\": " << schema << "}" << COLOR_RESET << std::endl;
}

// 编辑表内容
void editTable(const std::vector<std::string>& args) {
    if (args.size() < 3) {
        std::cout << COLOR_RED << "{\"error\": \"参数无效。用法：edittable <tableName> <newDataJSON>\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::string tableName = args[1];
    std::string newDataStr = args[2];
    json newData;

    try {
        newData = json::parse(newDataStr);
    } catch (json::parse_error& e) {
        std::cout << COLOR_RED << "{\"error\": \"无效的JSON数据\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::string path = config["dataDirectory"].get<std::string>() + "/" + tableName + ".json";
    json tableData;

    if (!std::filesystem::exists(path)) {
        std::cout << COLOR_RED << "{\"error\": \"表未找到\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::ifstream tableFile(path);
    tableFile >> tableData;

    tableData.merge_patch(newData);

    std::ofstream updatedTableFile(path);
    updatedTableFile << std::setw(4) << tableData << std::endl;

    std::cout << COLOR_GREEN << "{\"message\": \"表已更新\", \"table\": " << tableData << "}" << COLOR_RESET << std::endl;
}

// 查询表内容
void queryTable(const std::vector<std::string>& args) {
    if (args.size() < 2) {
        std::cout << COLOR_RED << "{\"error\": \"参数无效。用法：querytable <tableName>\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::string tableName = args[1];
    std::string path = config["dataDirectory"].get<std::string>() + "/" + tableName + ".json";

    if (!std::filesystem::exists(path)) {
        std::cout << COLOR_RED << "{\"error\": \"表未找到\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::ifstream tableFile(path);
    json tableData;
    tableFile >> tableData;

    std::cout << COLOR_CYAN << "{\"table\": " << tableData << "}" << COLOR_RESET << std::endl;
}

// 显示帮助信息
void showHelp() {
    std::cout << COLOR_YELLOW << "可用命令：" << COLOR_RESET << std::endl;
    std::cout << COLOR_GREEN << "  createuser <username> <password>  " << COLOR_RESET << "或 " << COLOR_CYAN << "cu <username> <password>" << COLOR_RESET << " - 创建用户" << std::endl;
    std::cout << COLOR_GREEN << "  createtable <tableName> <schema> " << COLOR_RESET << "或 " << COLOR_CYAN << "ct <tableName> <schema>" << COLOR_RESET << " - 创建表" << std::endl;
    std::cout << COLOR_GREEN << "  edittable <tableName> <newData>  " << COLOR_RESET << "或 " << COLOR_CYAN << "et <tableName> <newData>" << COLOR_RESET << " - 编辑表" << std::endl;
    std::cout << COLOR_GREEN << "  querytable <tableName>           " << COLOR_RESET << "或 " << COLOR_CYAN << "qt <tableName>" << COLOR_RESET << " - 查询表" << std::endl;
    std::cout << COLOR_GREEN << "  exit                             " << COLOR_RESET << "或 " << COLOR_CYAN << "e" << COLOR_RESET << " - 退出程序" << std::endl;
    std::cout << COLOR_GREEN << "  help                             " << COLOR_RESET << "或 " << COLOR_CYAN << "h" << COLOR_RESET << " - 显示帮助" << std::endl;
}

// 处理输入命令
void processInput(const std::string& input, bool& exitFlag) {
    std::istringstream argsStream(input);
    std::vector<std::string> commandArgs;
    std::string arg;
    while (argsStream >> arg) commandArgs.push_back(arg);

    if (commandArgs.empty()) {
        std::cout << COLOR_RED << "{\"error\": \"命令为空\"}" << COLOR_RESET << std::endl;
        return;
    }

    std::string command = commandArgs[0];
    std::transform(command.begin(), command.end(), command.begin(), ::tolower);

    if (command == "exit" || command == "e") {
        exitFlag = true;
    } else if (command == "createuser" || command == "cu") {
        createUser(commandArgs);
    } else if (command == "createtable" || command == "ct") {
        createTable(commandArgs);
    } else if (command == "edittable" || command == "et") {
        editTable(commandArgs);
    } else if (command == "querytable" || command == "qt") {
        queryTable(commandArgs);
    } else if (command == "help" || command == "h") {
        showHelp();
    } else {
        std::cout << COLOR_RED << "{\"error\": \"无效命令\"}" << COLOR_RESET << std::endl;
    }
}

int main() {
    struct termios oldt, newt;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);

    initializeConfig();
    std::filesystem::create_directories(config["dataDirectory"]);

    std::vector<std::string> history;
    std::string currentInput;
    int historyPos = 0;
    bool exitFlag = false;

    std::cout << COLOR_BLUE << "欢迎使用命令行工具！输入 'help' 或 'h' 查看帮助。" << COLOR_RESET << std::endl;
    std::cout << COLOR_MAGENTA << "输入命令：" << COLOR_RESET;
    std::cout.flush();

    while (!exitFlag) {
        char c;
        if (read(STDIN_FILENO, &c, 1) <= 0) continue;

        if (c == '\n') {
            std::cout << "\n";
            if (!currentInput.empty()) {
                history.push_back(currentInput);
                historyPos = history.size();
                processInput(currentInput, exitFlag);
                currentInput.clear();
            }
            if (!exitFlag) {
                std::cout << COLOR_MAGENTA << "输入命令：" << COLOR_RESET;
                std::cout.flush();
            }
        } else if (c == 27) { // ESC序列
            char seq[2];
            if (read(STDIN_FILENO, &seq[0], 1) > 0 && 
                read(STDIN_FILENO, &seq[1], 1) > 0) {
                if (seq[0] == '[') {
                    if (seq[1] == 'A' && historyPos > 0) { // 上
                        historyPos--;
                        currentInput = history[historyPos];
                    } else if (seq[1] == 'B' && historyPos < history.size()) { // 下
                        historyPos = (historyPos < history.size()-1) ? ++historyPos : history.size();
                        currentInput = (historyPos < history.size()) ? history[historyPos] : "";
                    }
                    std::cout << "\r\033[K" << COLOR_MAGENTA << "输入命令：" << COLOR_RESET << currentInput;
                    std::cout.flush();
                }
            }
        } else if (c == 127 || c == 8) { // 退格
            if (!currentInput.empty()) {
                currentInput.pop_back();
                std::cout << "\b \b";
                std::cout.flush();
            }
        } else {
            currentInput += c;
            std::cout << c;
            std::cout.flush();
        }
    }

    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    saveConfig();
    std::cout << COLOR_BLUE << "程序已退出。" << COLOR_RESET << std::endl;
    return 0;
}